总结
知识点
__filename:当前模块(js)的文件名。 这是当前的模块文件的绝对路径(符号链接会被解析)- 运行
node代码时,默认会注入modulerequire__filename__dirnameexports五个变量 - node.js中使用
require(".")相当于require("./"),相当于require("./index.js"),也就是查找本地目录的index.js
优秀的文件操作库
pkg-dir
找到 npm 或者 node.js 项目的根目录
findup
通过遍历父级目录查账文件或文件夹
locate-path
从多个文件中获取第一个存在的路径
path-exists
检查路径是否存在
resolve-cwd
从当前工作目录,像 require.resolve 一样解析模块路径
resolve-from
从给定路径,像 require.resolve 一样解析模块路径
涉及到的 node.js 方法
process.cwd()返回 Node.js 进程的当前工作目录(working directory)。
path.dirname()
path.resolve()相对路径转换成真实路径path.parse()
fs.accessSync(filepath)判断文件是否存在(能访问到),不存在会抛出异常
path.relative()
path.join()
Node.js 模块路径解析流程
Node.js项目模块路径解析是通过require.resolve方法来实现的require.resolve就是通过Module._resolveFileName方法实现的Module._resolveFileName方法核心流程有 3 点:判断是否为内置模块
NativeModule.canBeRequireByUsers()判断是否是可以被加载的内置模块通过
Module._resolveLookupPaths方法生成node_modules可能存在的路径- 如果路径为
/(根目录),直接返回['/node_modules'] - 否则,将路径字符串从后往前遍历,查询到
/时,拆分路径,在后面加上node_modules,并传入一个paths数组,直至查询不到
- 如果路径为
通过
zModule._findPath查询模块的真实路径
Module._findPath核心流程有 4 点:- 查询缓存(将
request和paths通过\x00合并成cacheKey) - 遍历
paths,将path与request组成文件路径basePath - 如果 basePath 存在则调用
<code>fs.realPathSync</code>获取文件真实路径 - 将文件真实路径缓存到
<code>Module._pathCache</code>(key 就是前面生成的 cacheKey)
- 查询缓存(将
fs.realPathSync核心流程有 3 点:- 查询缓存(缓存的 key 为 p,即
Module._findPath中生成的文件路径) - 从左往右遍历路径字符串,查询到
/时,拆分路径,判断该路径是否为软链接,如果是软链接则查询真实链接,并生成新路_径 p,然后继续往后遍历,这里有 1 个细节需要特别注意: - 遍历过程中生成的子路径 base 会缓存在 knownHard 和 cache 中,避免重复查询
- 遍历完成得到模块对应的真实路径,此时会将原始路径 original 作为 key,真实路径作为 value,保存到缓存中
- 查询缓存(缓存的 key 为 p,即
require.resolve.paths等价于Module._resolveLookupPaths,该方法用于获取所有node_modules可能存在的路径

图中知识点列表:
- 通过
require加载模块以后,会向Module._pathCache对象中添加该模块的路径,key:模块名称加\x00路径,value:实际路径 stat(path):查看文件状态。-2 不存在, 0 文件,1 文件夹realPathCache是一个Map对象linuxstat命令打印文件相关信息dev_t设备编号、ino_t文件的唯一标识fs.realPathSync在拿到软连接指向的真实路径后,还会在遍历,查看指向的路径是否还是一个软连接
正则表达式
Modules._findPath() 中的正则 /(?:^|\/)\.?\$/ 匹配 ..、/..。包含知识点
?匹配0到1个(?:)表示非匹配分组,作用是不保存括号中匹配的内容/^/匹配的是个空字符串'',任意字符都能匹配成功,任意字符中都有空字符串/[^]/表示非
为什么选择commander, 而不是yrags
两者差不多,都是Nodejs命令行工具,lerna选择的是yargs,
但是commander比yargs的热度高
https://www.npmtrends.com/commander-vs-yargs
